using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using Xunit;

namespace Tsual.DataPipeline.Test
{
    public class UnitTest1
    {
        [Fact]
        public async Task Test1Async()
        {
            var meta = "123";
            var pipeline = new DataPipeline<string, string>(type => null).AddPipe<EchoPipe>();
            var result = await pipeline.ReadAsync(meta);
            Assert.Equal(DataPipelineExcutionStatus.Success, result.ReadStatus);
            Assert.Equal(meta, result.Data);
        }

        [Fact]
        public async Task Test2Async()
        {
            var meta = "123";
            var map = new Dictionary<string, string>();
            var pipeline = new DataPipeline<string, string>(type => map).AddPipe<StringDictionaryPipe>().AddPipe<StringDictionaryPipe>().AddPipe<EchoPipe>();
            var result = await pipeline.ReadAsync(meta);
            Assert.Equal(DataPipelineExcutionStatus.Success, result.ReadStatus);
            Assert.Equal(DataPipelineExcutionStatus.Success, result.WriteStatus);
            Assert.Equal(meta, result.Data);
            using (var ws = new StreamWriter(File.OpenWrite("datapipe-test-trace-result.json"))) { ws.Write(JsonConvert.SerializeObject(result)); ws.Flush(); }
        }

        [Fact]
        public void Test3()
        {

            var type = typeof(List<int>);
            var type0 = typeof(List<>);
            var type1 = typeof(abc);
        }
    }

    public class abc : List<int> { }

    public class EchoPipe : IDataPipeDescription<string, string>
    {
        public bool CanRead(string meta) => true;

        public bool CanWrite(string data, string meta) => true;

        public Task<DataPipeReadResult<string>> Read(string meta) => Task.Run(() => DataPipeReadResult<string>.Success(meta));

        public Task<DataPipeWriteResult> Write(string data, string meta) => Task.Run(() => DataPipeWriteResult.Success());
    }

    public class StringDictionaryPipe : IDataPipeDescription<string, string>
    {
        Dictionary<string, string> map;

        public StringDictionaryPipe(Dictionary<string, string> map)
        {
            this.map = map ?? throw new ArgumentNullException(nameof(map));
        }

        public bool CanRead(string meta) => !string.IsNullOrEmpty(meta);

        public bool CanWrite(string data, string meta) => !string.IsNullOrEmpty(meta);

        public Task<DataPipeReadResult<string>> Read(string meta) => Task.Run(() => map.ContainsKey(meta) ? DataPipeReadResult<string>.Success(map[meta]) : DataPipeReadResult<string>.Notfound());

        public Task<DataPipeWriteResult> Write(string data, string meta) => Task.Run(() =>
        {
            if (!map.ContainsKey(meta)) map.Add(meta, data);
            else map[meta] = data;
            return DataPipeWriteResult.Success();
        });
    }
}
